package cn.ckx.coding.advice;

import cn.ckx.coding.common.annotation.http.IgnoreResponseEntityWrap;
import cn.ckx.coding.common.dto.ApiResponse;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.lang.NonNull;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.lang.reflect.Method;
import java.util.Objects;

/**
 * @ClassName ResponseBodyWrapping
 * @Description
 * 
 *  统一http输出
 * 
 * @Author kunxin.cai
 * @Date 2021/5/11
 * @Version 1.0
 **/
@ControllerAdvice
public class ResponseBodyWrapping implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(@NonNull MethodParameter methodParameter,@NonNull Class<? extends HttpMessageConverter<?>> aClass) {
        try {
            Method method = Objects.requireNonNull(methodParameter.getMethod());
            Class<?> returnType = method.getReturnType();

            if (returnType == null) {
                return true;
            }

            if (method.isAnnotationPresent(IgnoreResponseEntityWrap.class)) {
                return false;
            }
            if (Objects.equals(returnType, ByteArrayHttpMessageConverter.class)) {
                return false;
            }
            if (Objects.equals(returnType, ResponseEntity.class)) {
                return false;
            }
            if (Objects.equals(returnType, ApiResponse.class)) {
                return false;
            }

        }catch (NullPointerException e) {
            return true;
        }
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body,@NonNull  MethodParameter methodParameter,@NonNull MediaType mediaType,@NonNull Class<? extends HttpMessageConverter<?>> aClass,@NonNull ServerHttpRequest serverHttpRequest,@NonNull ServerHttpResponse serverHttpResponse) {
        if(Objects.isNull(body)){
            return ApiResponse.ok();
        }
        return ApiResponse.ok().of(body);
    }
}
